Skip to content

fix: mandatory provider_skill_id and strict catalog validation#317

Merged
yacosta738 merged 4 commits intomainfrom
fix/skill-id-validation-959229972059906167
Apr 6, 2026
Merged

fix: mandatory provider_skill_id and strict catalog validation#317
yacosta738 merged 4 commits intomainfrom
fix/skill-id-validation-959229972059906167

Conversation

@yacosta738
Copy link
Copy Markdown
Contributor

Implemented mandatory provider_skill_id in JSON output, updated specification for backward compatibility requirements, fixed local source resolution to use full provider IDs, and added strict validation for provider_skill_id format in the catalog. All tests passed.


PR created automatically by Jules for task 959229972059906167 started by @yacosta738

- Update spec.md: make provider_skill_id mandatory in JSON.
- Fix skill.rs: use full ID for local source resolution.
- Fix catalog.rs: strictly validate provider_skill_id.
- Update tests to align with new rules.

Co-authored-by: yacosta738 <33158051+yacosta738@users.noreply.github.com>
@google-labs-jules
Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 4, 2026

📝 Walkthrough

Summary by CodeRabbit

  • Documentation

    • provider_skill_id is now required in JSON serialization (was optional); compatibility rules tightened to preserve existing field names/types/semantics and keep new provider IDs additive.
  • Bug Fixes

    • Validation added to enforce provider_skill_id format (owner/repo/skill-like), causing earlier detection of invalid values.
    • Local resolution now prefers provider-qualified local skill paths when available.
  • Tests

    • Fixtures and tests updated to use fully-qualified provider skill IDs and adjusted source paths.

Walkthrough

Require provider_skill_id in serialized recommendations, validate provider-qualified IDs in the catalog, prefer provider-qualified local paths for test fallback resolution, and update tests/fixtures to use fully-qualified provider skill identifiers.

Changes

Cohort / File(s) Summary
Specification
openspec/specs/skill-recommendations/spec.md
Tightened JSON schema: SuggestJsonRecommendation.provider_skill_id changed from SHOULD to MUST; clarified backward-compatibility language to preserve existing field names/types/semantics and mark provider_skill_id as additive.
Skill catalog validation
src/skills/catalog.rs
Added validate_provider_skill_id and invoked it from normalize_skill_definition; enforces qualified provider_skill_id format (no leading/trailing slashes, no empty/./.. segments, only alnum/./_/- chars, at least two /-separated segments).
Provider local path resolution
src/skills/provider.rs
local_catalog_skill_source_dir now accepts provider_skill_id and first tries AGENTSYNC_TEST_SKILL_SOURCE_DIR joined with the full provider-qualified ID, falling back to local_skill_id if absent; resolve_catalog_install_source passes the provider-qualified ID through.
Install resolution (test fallback)
src/commands/skill.rs
When using AGENTSYNC_TEST_SKILL_SOURCE_DIR, SuggestInstallProvider::resolve constructs the candidate source_path by joining the test root with the full id (provider-qualified), changing which on-disk directory is checked for qualified IDs.
Tests / Fixtures
tests/integration/skill_suggest.rs, tests/unit/suggest_catalog.rs
Updated test paths and fixtures to use fully-qualified provider skill IDs (e.g., dallay/agents-skills/...), and adjusted an integration test's failing source directory to the nested provider path.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hop with joy at every slash,
provider names now snug and brash.
Specs say MUST, checks nod along,
paths align and tests sing a song.
A rabbit's cheer for tidy craft!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main changes: making provider_skill_id mandatory and implementing strict catalog validation for the skill ID format.
Description check ✅ Passed The description is directly related to the changeset, covering the implementation of mandatory provider_skill_id, specification updates, local source resolution fixes, and validation additions.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/skill-id-validation-959229972059906167

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@sentry
Copy link
Copy Markdown

sentry bot commented Apr 4, 2026

Codecov Report

❌ Patch coverage is 82.85714% with 6 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/skills/catalog.rs 84.61% 4 Missing ⚠️
src/commands/skill.rs 0.00% 1 Missing ⚠️
src/skills/provider.rs 87.50% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/skills/catalog.rs`:
- Around line 790-794: validate_provider_skill_id currently only checks for at
least one '/', allowing traversal or malformed values like '../x/y', '/x/y', or
'x/../y'; update validate_provider_skill_id to split provider_skill_id on '/'
and enforce at least two segments, ensure no segment is empty, no segment equals
"." or "..", and reject any input that starts with or ends with a slash;
additionally restrict each segment to a safe character class (e.g., alphanumeric
plus dot, underscore, hyphen) so only path-safe relative segments are allowed
(apply these checks inside validate_provider_skill_id and return an error/bail
for any violation).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ed3a0f34-d1cb-4b25-9001-0449caaa1a0a

📥 Commits

Reviewing files that changed from the base of the PR and between 8aed5a3 and a08496a.

📒 Files selected for processing (6)
  • openspec/specs/skill-recommendations/spec.md
  • spec.patch
  • src/commands/skill.rs
  • src/skills/catalog.rs
  • tests/integration/skill_suggest.rs
  • tests/unit/suggest_catalog.rs

@yacosta738 yacosta738 marked this pull request as ready for review April 4, 2026 14:45
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
openspec/specs/skill-recommendations/spec.md (1)

854-875: ⚠️ Potential issue | 🟠 Major

The compatibility wording now contradicts the requirement.

This section says provider_skill_id MUST be serialized, but the scenario below says the field is “allowed but not required.” That makes the contract ambiguous, and the earlier JSON example still omits the field entirely. Reword this as “producers MUST emit provider_skill_id; existing consumers MAY ignore it” and update the example to match.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@openspec/specs/skill-recommendations/spec.md` around lines 854 - 875, Update
the spec text to remove the contradiction by making producers required to emit
provider_skill_id and consumers optional to read it: change the sentence to
"producers MUST emit `provider_skill_id`; existing consumers MAY ignore it" and
update the JSON example and the Scenario descriptions for
`SuggestJsonRecommendation` so the example includes a `"provider_skill_id":
"dallay/agents-skills/makefile"` alongside `"skill_id"`,
`"matched_technologies"`, `"reasons"`, and `"installed"`, keeping those fields
unchanged; ensure references to `SuggestJsonRecommendation`,
`provider_skill_id`, `skill_id`, `matched_technologies`, `reasons`, and
`installed` are updated so the contract is unambiguous about emission vs.
consumer handling.
♻️ Duplicate comments (1)
src/skills/catalog.rs (1)

1039-1044: ⚠️ Potential issue | 🟠 Major

provider_skill_id validation is still too weak.

Counting slashes alone still accepts malformed IDs like ../x/y, /x/y, or owner//skill. That misses the “strict validation” goal here and still leaves the new full-ID lookup path exposed to traversal-style values. Validate path components instead of separator count: require a relative path, reject empty/./.. segments, and reject leading/trailing slashes or backslashes.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/skills/catalog.rs` around lines 1039 - 1044, The current
validate_provider_skill_id function
(validate_provider_skill_id(provider_skill_id: &str)) is too weak; change it to
validate components instead of counting slashes: ensure the string does not
start or end with '/' or '\\', split on '/' and require at least two components,
and for each component reject empty strings and the single-segment values "." or
".."; if any check fails, bail with a clear error message. Keep the function
signature and Result return type, and perform these checks before returning
Ok(()) so traversal-styled or malformed IDs like "/x/y", "../x/y",
"owner//skill", or segments with "."/".." are rejected.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/commands/skill.rs`:
- Around line 945-947: The fallback that uses AGENTSYNC_TEST_SKILL_SOURCE_DIR
and PathBuf::from(source_root).join(id) doesn't cover embedded catalog installs
because the catalog branch (catalog.get_skill_definition(id)) still resolves
test sources via resolve_catalog_install_source(..., local_skill_id, ...);
update resolve_catalog_install_source (and any code in the
catalog.get_skill_definition path) to also try the same
AGENTSYNC_TEST_SKILL_SOURCE_DIR layouts (both source_root.join(id) and the
alternative embedded layout used by embedded skills like "rust-async-patterns"),
or refactor the lookup into a shared helper that probes both layouts and replace
the current per-branch logic so embedded-catalog installs are discovered
consistently.

---

Outside diff comments:
In `@openspec/specs/skill-recommendations/spec.md`:
- Around line 854-875: Update the spec text to remove the contradiction by
making producers required to emit provider_skill_id and consumers optional to
read it: change the sentence to "producers MUST emit `provider_skill_id`;
existing consumers MAY ignore it" and update the JSON example and the Scenario
descriptions for `SuggestJsonRecommendation` so the example includes a
`"provider_skill_id": "dallay/agents-skills/makefile"` alongside `"skill_id"`,
`"matched_technologies"`, `"reasons"`, and `"installed"`, keeping those fields
unchanged; ensure references to `SuggestJsonRecommendation`,
`provider_skill_id`, `skill_id`, `matched_technologies`, `reasons`, and
`installed` are updated so the contract is unambiguous about emission vs.
consumer handling.

---

Duplicate comments:
In `@src/skills/catalog.rs`:
- Around line 1039-1044: The current validate_provider_skill_id function
(validate_provider_skill_id(provider_skill_id: &str)) is too weak; change it to
validate components instead of counting slashes: ensure the string does not
start or end with '/' or '\\', split on '/' and require at least two components,
and for each component reject empty strings and the single-segment values "." or
".."; if any check fails, bail with a clear error message. Keep the function
signature and Result return type, and perform these checks before returning
Ok(()) so traversal-styled or malformed IDs like "/x/y", "../x/y",
"owner//skill", or segments with "."/".." are rejected.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 61494ac4-d999-4cab-b44f-5d5a4313ea74

📥 Commits

Reviewing files that changed from the base of the PR and between a08496a and 3f7c824.

📒 Files selected for processing (5)
  • openspec/specs/skill-recommendations/spec.md
  • src/commands/skill.rs
  • src/skills/catalog.rs
  • tests/integration/skill_suggest.rs
  • tests/unit/suggest_catalog.rs

- Fix rustfmt in suggest_catalog.rs (line formatting)
- Fix local source resolution to use full provider_skill_id path in AGENTSYNC_TEST_SKILL_SOURCE_DIR
- Strengthen provider_skill_id validation to reject malformed IDs (empty segments, ., .., leading/trailing slashes)
- Update spec to clarify producer MUST emit provider_skill_id, consumers MAY ignore it
- Update JSON example in spec to include provider_skill_id
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/unit/suggest_catalog.rs (1)

1000-1011: ⚠️ Potential issue | 🟡 Minor

Test fixture uses invalid provider_skill_id format that will be silently rejected.

provider_skill("makefile", "makefile") creates a skill with provider_skill_id = "makefile", which violates the new validation requiring at least two /-separated segments. Since overlay_catalog uses lenient validation, this entry will be silently skipped.

The test may pass coincidentally (rust detection falls back to embedded catalog), but the provider overlay isn't being applied as intended.

🔧 Proposed fix
     fn recommendation_catalog(&self) -> Result<Option<ProviderCatalogMetadata>> {
         let detect = DetectionRules {
             config_files: Some(vec!["Makefile".to_string()]),
             ..Default::default()
         };

         Ok(Some(ProviderCatalogMetadata {
             provider: "detect-metadata-provider".to_string(),
             version: "2026.03".to_string(),
             schema_version: "v1".to_string(),
-            skills: vec![provider_skill("makefile", "makefile")],
+            skills: vec![provider_skill("dallay/agents-skills/makefile", "makefile")],
             technologies: vec![ProviderCatalogTechnology {
                 id: "make".to_string(),
                 name: "Make".to_string(),
-                skills: vec!["makefile".to_string()],
+                skills: vec!["dallay/agents-skills/makefile".to_string()],
                 detect: Some(detect),
                 min_confidence: Some("low".to_string()),
                 reason_template: None,
             }],
             combos: vec![],
         }))
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/unit/suggest_catalog.rs` around lines 1000 - 1011, The test fixture is
creating a skill with provider_skill_id "makefile" which fails the new
validation requiring at least two '/'-separated segments; update the call to
provider_skill in tests/unit/suggest_catalog.rs (the provider_skill(...)
invocation that constructs the skills vec) to use a valid provider_skill_id with
at least two segments (e.g. "provider/makefile" or "provider/make/skill") so the
overlay_catalog will accept and apply the provider overlay as intended; keep the
rest of the skill arguments the same.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@tests/unit/suggest_catalog.rs`:
- Around line 1000-1011: The test fixture is creating a skill with
provider_skill_id "makefile" which fails the new validation requiring at least
two '/'-separated segments; update the call to provider_skill in
tests/unit/suggest_catalog.rs (the provider_skill(...) invocation that
constructs the skills vec) to use a valid provider_skill_id with at least two
segments (e.g. "provider/makefile" or "provider/make/skill") so the
overlay_catalog will accept and apply the provider overlay as intended; keep the
rest of the skill arguments the same.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4158ebaf-7a66-4e64-ba1e-0457d72d7e3e

📥 Commits

Reviewing files that changed from the base of the PR and between 3f7c824 and ecad40f.

📒 Files selected for processing (4)
  • openspec/specs/skill-recommendations/spec.md
  • src/skills/catalog.rs
  • src/skills/provider.rs
  • tests/unit/suggest_catalog.rs

@yacosta738 yacosta738 merged commit 3bf59f9 into main Apr 6, 2026
25 of 26 checks passed
@yacosta738 yacosta738 deleted the fix/skill-id-validation-959229972059906167 branch April 6, 2026 18:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant